//GN1621驱动段码屏，COM4 * SEG32
//写模式: 占空比 50%, 时钟频率: 4~150KHz, 取 ((150+4)/2)KHz左右的频率
//77KHz,得出H占空比时间:12.9us,取12us,对频率: 83.3KHz
//运行环境: 多任务
//为避免被多任务打断数据传输,数据传输必须在最高级的任务执行

//参考时序
//CS Delay 2us, CLK, DATA, Delay 2us, CS
// DATA 在 CLK中间跳变, CLK上升沿读取DATA有效
//上电后: CS 6个, 每个50us不到
//  CS(L近50us一个), Delay 2us, CLK(2us 一位, 一个CS里面有 12个), 
//  CS H, Delay 2us, CS L, 
//100 0010 1001 0 //4COM 1/3 bias
//100 0001 1000 0 //RC内部震荡时钟
//100 0000 0000 0 //Sys Dis
//100 0000 0101 0 //WDT Dis
//100 0000 0001 0 //Sys En
//100 0000 0011 0 //LCD ON

//101 79个0 4个1 01 0011111 01 0011 37个0 
//101 80个0 5个1 5个0 110010011110 32个0  总时间大概500us

//100 0010 1001 0 100 

#include "GN1621.h"
#include "GN1621_Pin.h"
#include "GN1621_Parts_Num.h"
#include "UI.h"



//驱动上电默认: SYS DIS, LCD OFF, TONE OFF, RC 256K, IRQ Dis, F128, TNORMAL

#define GN_Cmd_BIAS_COM 0B100001010010
#define GN_Cmd_RC_En    0B100000110000
#define GN_Cmd_Sys_Dis  0B100000000000
#define GN_Cmd_WDT_Dis  0B100000001010
#define GN_Cmd_Sys_En   0B100000000010
#define GN_Cmd_LCD_ON   0B100000000110
#define GN_Cmd_LCD_OFF  0B100000000100

void GN162X_Delay(unsigned char n)
{
    while(n--)
    {
        asm("nop");
    }
}

#define GN_Delay_2us() GN162X_Delay(2);
#define GN_Delay_1us() GN162X_Delay(1);

GN1621_Device_S GN_Device;

#define GN_RAM_Length 16
uint8_t GN_RAM[GN_RAM_Length];
uint16_t UI_All_ShineCount = 0; //Tick 200ms
extern uint8_t Factory_Enable;

void GN_RAM_Refresh(Cad_Dat_S Cad_Dat)
{
    uint8_t x_4 = 0;
    uint8_t x_H = 0;
    uint8_t x_Seq = 0;

    x_Seq = Cad_Dat.Cad_Seg / 2;
    x_H = Cad_Dat.Cad_Seg % 2;
    if(x_Seq < GN_RAM_Length)
    {
        x_4 = Cad_Dat.Cad_Com;
        if(x_H > 0) x_4 <<= 4;

        if(Cad_Dat.Cad_Dis == Char_ON) GN_RAM[x_Seq] |= x_4;
        else GN_RAM[x_Seq] &= (~x_4);
    }
}

//写数据,从高位开始写
void GN1621_Write_All(void)
{
    uint8_t i;
    uint16_t temp_Bit;
    uint8_t bit = 0;
    uint16_t p = 0;
    uint8_t j = 0;
    static uint8_t shine_count = 0;
    static uint8_t shine = 0;

    GN1621_WR_Handled(1);
    GN1621_Data_Handled(1);
    GN1621_CS_Handled(0);
    GN_Delay_1us();

    temp_Bit = 0x100;
    p = 0B101000000;
    for (i = 0; i < 9; i++)
    { //101 + Address
        bit = ((p & temp_Bit) == temp_Bit)?1:0;
        GN1621_WR_Handled(0);
        GN_Delay_1us();
        GN1621_Data_Handled(bit);
        GN_Delay_1us();
        GN1621_WR_Handled(1);
        GN_Delay_2us();
        p <<= 1;
    }
    
    for (i = 0; i < GN_RAM_Length; i++)
    { //Data
        p = GN_RAM[i];

        if((UI_System.Grill_state == State_Grill_Idle) && (Factory_Enable == 0))
        {
            if(UI_All_ShineCount == 0) UI_All_ShineCount = 1;
            else if(UI_All_ShineCount >= 4)
            {
                UI_All_ShineCount = 0;
                if(shine_count < 3) 
                {
                    if(shine == 0) shine = 0xff; 
                    else
                    {
                        shine = 0x00;
                        shine_count++;
                    }
                } 
                else shine = 0;
            }
            p = shine;
        }
        
        for (j = 0; j < 8; j++)
        { //COM0 => COM3, Seg0
            bit = ((p & 0x1) == 0x1)?1:0;
            GN1621_WR_Handled(0);
            GN_Delay_1us();
            GN1621_Data_Handled(bit);
            GN_Delay_1us();
            GN1621_WR_Handled(1);
            GN_Delay_2us();
            p >>= 1;
        }
    }

    GN1621_CS_Handled(1);
    GN1621_WR_Handled(1);
    GN1621_Data_Handled(1);
}
void GN1621_Cmd_Tx(uint16_t p)
{
    uint8_t i;
    uint16_t temp_Bit;
    uint8_t bit = 0;

    temp_Bit = 0x800;
    for (i = 0; i < 12; i++)
    {
        bit = ((p & temp_Bit) == temp_Bit)?1:0;
        if(i == 0)
        {
            GN1621_WR_Handled(1);
            GN1621_Data_Handled(1);
            GN1621_CS_Handled(0);
            GN_Delay_2us();
        } 
        GN1621_WR_Handled(0);
        GN_Delay_1us();
        GN1621_Data_Handled(bit);
        GN_Delay_1us();
        GN1621_WR_Handled(1);
        GN_Delay_2us();
        p <<= 1;

        if(i == 11)
        {
            GN1621_CS_Handled(1);
            GN1621_WR_Handled(1);
            GN1621_Data_Handled(1);
            GN_Delay_2us();
        }
    }
}

void GN1621_RAM_Reset(uint8_t p)
{
    uint8_t i;

    for (i = 0; i < GN_RAM_Length; i++)
    {
        GN_RAM[i] = p;
    }
    GN1621_Write_All();
}

void GN1621_ON(void)
{
    GN1621_Cmd_Tx(GN_Cmd_BIAS_COM);
    GN1621_Cmd_Tx(GN_Cmd_RC_En);
    GN1621_Cmd_Tx(GN_Cmd_Sys_Dis);
    GN1621_Cmd_Tx(GN_Cmd_WDT_Dis);
    GN1621_Cmd_Tx(GN_Cmd_Sys_En);
    GN1621_Cmd_Tx(GN_Cmd_LCD_ON);

    GN1621_RAM_Reset(0x00);
    GN_Delay_2us();
    Lcd_Backlight_ON;

    UI_System.LCD_State = UI_ON;
}
void GN1621_OFF(void)
{
    GN1621_Cmd_Tx(GN_Cmd_Sys_Dis);
    GN1621_Cmd_Tx(GN_Cmd_WDT_Dis); 
    GN1621_Cmd_Tx(GN_Cmd_LCD_OFF); 
    Lcd_Backlight_OFF;

    GN1621_RAM_Reset(0x00); 
    GN_Delay_2us();

    UI_System.LCD_State = UI_OFF;
}

void GN1621_Init(void)
{
    GN1621_Pin_Config();
    GN1621_ON();
	// GN1621_RAM_Reset(0xff);
    Lcd_Parts_Init();
    UI_Init();
	
}
void GN1621_Main(void)
{

}
//Tick 200ms
void GN1621_Clock(void)
{
    if(UI_System.LCD_State == UI_ON) GN1621_Write_All();

    if((UI_All_ShineCount > 0) && (UI_All_ShineCount < 0xffff)) UI_All_ShineCount++;
}
